<template>
  <div class="right-panel">
    <LoadingDialog ref="loadingDialog"/>
    <div class="history-box">
      <h4 class="history-title">生成历史</h4>
      <div class="scroll-container" ref="scroller">
        <div class="button-wrapper">
          <button 
            v-for="button in buttons" 
            :key="button.id" 
            class="scroll-button"
            :class="{ active: activeButtonId === button.id }"
            @click="handleButtonClick(button)"
          >
            {{ button.label }}
          </button>
          <div v-if="!buttons.length" class="no-history">
            暂无历史记录
          </div>
        </div>
      </div>
    </div>

    <div class="content-column">
      <!-- 评测文章区域 -->
      <div class="article-section">
        <div class="article-header">
          <div class="template-input-container">
          </div>
          <button 
            @click="generateArticle" 
            class="generate-article-btn"
            :disabled="isGeneratingArticle || isGeneratingOpinion || isGeneratingTitle"
          >
            {{ isGeneratingArticle ? '生成中...' : '生成评测文章' }}
          </button>
        </div>
        <div class="display-box">
          <div v-if="!streamingArticle" class="placeholder">
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="placeholder-icon"><path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path></svg>
            <h3>评测文章生成区</h3>
            <p>点击上方的"生成评测文章"按钮<br/>即可在此处查看流式生成的完整内容。</p>
          </div>
          <div v-else v-html="streamingArticle" ref="streamingArticleRef"></div>
        </div>
      </div>

      <!-- 价值点文章区域 -->
      <div class="article-section">
        <div class="article-header">
          <div class="spacer"></div>
          <button 
            @click="generateOpinionArticle" 
            class="generate-article-btn"
            :disabled="isGeneratingArticle || isGeneratingOpinion || isGeneratingTitle"
          >
            {{ isGeneratingOpinion ? '生成中...' : '生成价值文章' }}
          </button>
        </div>
        <div class="display-box">
          <div v-if="!opinionArticle" class="placeholder">
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="placeholder-icon"><path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path></svg>
            <h3>价值点文章生成区</h3>
            <p>点击上方的"生成价值点文章"按钮<br/>即可在此处查看流式生成的完整内容。</p>
          </div>
          <div v-else v-html="opinionArticle" ref="opinionArticleRef"></div>
        </div>
      </div>

      <!-- 标题生成区域 -->
      <div class="article-section">
        <div class="article-header">
          <div class="title-controls">
            <select v-model="titleStyle" class="title-select">
              <option value="">选择风格</option>
              <option value="小鸡">小鸡</option>
              <option value="房小团">房小团</option>
              <option value="购房通">购房通</option>
            </select>
            <select v-model="titleType" class="title-select">
              <option value="">选择类型</option>
              <option value="市场">市场</option>
              <option value="项目">项目</option>
              <option value="政策">政策</option>
            </select>
          </div>
          <button 
            @click="generateTitle" 
            class="generate-article-btn"
            :disabled="isGeneratingArticle || isGeneratingOpinion || isGeneratingTitle"
          >
            {{ isGeneratingTitle ? '生成中...' : '生成标题' }}
          </button>
        </div>
        <div class="display-box">
          <div v-if="!generatedTitle" class="placeholder">
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="placeholder-icon"><path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path></svg>
            <h3>标题生成区</h3>
            <p>点击上方的"生成标题"按钮<br/>即可在此处查看生成的标题内容。</p>
          </div>
          <div v-else v-html="generatedTitle"></div>
        </div>
      </div>
    </div>
  </div>  
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import axios from 'axios';
import LoadingDialog from './LoadingDialog.vue';
import vSelect from 'vue-select';

const streamingArticle = ref('');
const opinionArticle = ref('');
const searchKeyword = ref('');
const selectedEstate = ref(null);
const estateOptions = ref([]);
const generatedTitle = ref('');
const titleStyle = ref('');
const titleType = ref('');
const isGeneratingArticle = ref(false); // 评测文章生成状态
const isGeneratingOpinion = ref(false); // 价值文章生成状态
const isGeneratingTitle = ref(false); // 标题生成状态
let controller = null; // 用于取消请求
let opinionController = null; // 用于取消价值文章请求
const loadingDialog = ref(null);
let updateTimer = null; // 用于防抖更新
let opinionUpdateTimer = null; // 用于价值文章防抖更新
const streamingArticleRef = ref(null); // 用于滚动到最新内容
const opinionArticleRef = ref(null); // 用于价值文章滚动到最新内容

// 防抖更新函数
const debouncedUpdate = (content) => {
  if (updateTimer) {
    clearTimeout(updateTimer);
  }
  updateTimer = setTimeout(() => {
    streamingArticle.value = content;
    // 自动滚动到最新内容
    if (streamingArticleRef.value) {
      streamingArticleRef.value.scrollTop = streamingArticleRef.value.scrollHeight;
    }
  }, 50); // 50ms防抖
};

// 价值文章防抖更新函数
const debouncedOpinionUpdate = (content) => {
  if (opinionUpdateTimer) {
    clearTimeout(opinionUpdateTimer);
  }
  opinionUpdateTimer = setTimeout(() => {
    opinionArticle.value = content;
    // 自动滚动到最新内容
    if (opinionArticleRef.value) {
      opinionArticleRef.value.scrollTop = opinionArticleRef.value.scrollHeight;
    }
  }, 50); // 50ms防抖
};

const generateArticle = async () => {
  console.log('generateArticle called, controller state:', !!controller);
  
  // 如果正在生成中，直接返回
  if (isGeneratingArticle.value || isGeneratingOpinion.value || isGeneratingTitle.value) {
    return;
  }
  
  // 检查是否已有请求在进行中
  if (controller) {
    // 如果controller存在但可能卡住了，强制重置
    try {
      controller.abort();
    } catch (e) {
      console.log('Controller abort error:', e);
    }
    controller = null;
    console.log('Forced controller reset');
  }
  
  isGeneratingArticle.value = true; // 设置生成状态
  streamingArticle.value = ''; // 清空旧内容
  controller = new AbortController();
  
  // 添加超时处理
  const timeoutId = setTimeout(() => {
    if (controller) {
      controller.abort();
      alert('请求超时，请重试');
    }
  }, 180000); // 180秒超时

  let opinins = window.localStorage.getItem('supplementaryMaterial');
  let reviewContent = window.localStorage.getItem('reviewContent');
  if (!opinins || !reviewContent) {
    alert('请先选择楼盘，生成价值点');
    return;
  }

  reviewContent = JSON.parse(reviewContent);

  let params = {
    opinions: opinins,
    base_info: reviewContent.base_info,
    location: reviewContent.location,
    comments: reviewContent.comments,
    plan: reviewContent.plan,
    apartment: reviewContent.apartment,
    choose: reviewContent.choose,
    market: reviewContent.market,
    comments: reviewContent.comments,
    other_info: reviewContent.other_info || '',
    hot_content: reviewContent.hot_content,
    estate_name: reviewContent.estate_name || '',
    estate_id: reviewContent.estate_id || '',
    opinion_article: opinionArticle.value,
    estate_type: window.localStorage.getItem('estate_type') || ''
  }
  
  try {
    const response = await fetch('/media/predict/test/create/estate/article', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': sessionStorage.getItem('Authorization') || ''
      },
      body: JSON.stringify(params),
      signal: controller.signal
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const reader = response.body.getReader();
    const decoder = new TextDecoder('utf-8');
    let buffer = ''; // 用于处理跨chunk的数据
    let isStreamComplete = false; // 标记流是否完成
    
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      
      // 将新数据添加到缓冲区
      buffer += decoder.decode(value, { stream: true });
      
      // 按行分割，但保留最后一行（可能不完整）
      const lines = buffer.split('\n');
      buffer = lines.pop() || ''; // 保留最后一行
      
      for (const line of lines) {
        if (line.trim() === '') continue;
        
        // 查找data: 前缀
        if (line.startsWith('data: ')) {
          const jsonStr = line.substring(6);
          
          if (jsonStr === '[DONE]') {
            console.log('Stream completed');
            isStreamComplete = true;
            continue;
          }
          
          try {
            const data = JSON.parse(jsonStr);
            
            // 检查是否是完整内容（流结束时的完整数据）
            if (data.content && typeof data.content === 'string' && isStreamComplete) {
              // 这是流结束后的完整内容，替换而不是追加
              const processedContent = data.content
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/\n/g, '<br>')
                .replace(/\r/g, '');
              
              streamingArticle.value = processedContent;
              console.log('Received complete content after stream, replaced');
              // 自动滚动到最新内容
              if (streamingArticleRef.value) {
                streamingArticleRef.value.scrollTop = streamingArticleRef.value.scrollHeight;
              }
            }
            // 处理token
            else if (data.token) {
              const token = data.token;
              const processedToken = token
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/\n/g, '<br>')
                .replace(/\r/g, '');
              
              streamingArticle.value += processedToken;
              // 自动滚动到最新内容
              if (streamingArticleRef.value) {
                streamingArticleRef.value.scrollTop = streamingArticleRef.value.scrollHeight;
              }
            }
          } catch (error) {
            console.error('JSON parse error:', jsonStr, error);
          }
        }
        // 如果不是SSE格式，尝试直接解析JSON
        else {
          try {
            const data = JSON.parse(line);
            
            // 检查是否是完整内容
            if (data.content && typeof data.content === 'string' && isStreamComplete) {
              const processedContent = data.content
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/\n/g, '<br>')
                .replace(/\r/g, '');
              
              streamingArticle.value = processedContent;
              console.log('Received complete content after stream, replaced');
              // 自动滚动到最新内容
              if (streamingArticleRef.value) {
                streamingArticleRef.value.scrollTop = streamingArticleRef.value.scrollHeight;
              }
            }
            // 处理token
            else if (data.token) {
              const token = data.token;
              const processedToken = token
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/\n/g, '<br>')
                .replace(/\r/g, '');
              
              streamingArticle.value += processedToken;
              // 自动滚动到最新内容
              if (streamingArticleRef.value) {
                streamingArticleRef.value.scrollTop = streamingArticleRef.value.scrollHeight;
              }
            }
          } catch (error) {
            // 不是JSON格式，忽略
          }
        }
      }
    }
  } catch (error) {
    if (error.name !== 'AbortError') {
      console.error('Fetch error:', error);
      streamingArticle.value = '生成失败: ' + error.message;
    }
  } finally {
    clearTimeout(timeoutId);
    controller = null;
    isGeneratingArticle.value = false; // 重置生成状态
  }
};

const generateOpinionArticle = async () => {
  console.log('generateOpinionArticle called, opinionController state:', !!opinionController);
  
  // 如果正在生成中，直接返回
  if (isGeneratingArticle.value || isGeneratingOpinion.value || isGeneratingTitle.value) {
    return;
  }
  
  // 检查是否已有请求在进行中
  if (opinionController) {
    // 如果opinionController存在但可能卡住了，强制重置
    try {
      opinionController.abort();
    } catch (e) {
      console.log('OpinionController abort error:', e);
    }
    opinionController = null;
    console.log('Forced opinionController reset');
  }
  
  isGeneratingOpinion.value = true; // 设置生成状态
  opinionArticle.value = ''; // 清空旧内容
  opinionController = new AbortController();
  
  // 添加超时处理
  const opinionTimeoutId = setTimeout(() => {
    if (opinionController) {
      opinionController.abort();
      alert('请求超时，请重试');
    }
  }, 180000); // 180秒超时

  let opinins = window.localStorage.getItem('supplementaryMaterial');
  let reviewContent = window.localStorage.getItem('reviewContent');
  if (!opinins || !reviewContent) {
    alert('请先选择楼盘，生成价值点');
    return;
  }

  reviewContent = JSON.parse(reviewContent);
  let params = {
    title: opinins,
    content: reviewContent.base_info + '用户评论:' + reviewContent.comments,
    hot_content: reviewContent.hot_content || '',
    other_info: reviewContent.other_info || ''
  }
  
  try {
    const response = await fetch('/media/predict/test/create/paragraph/by/opinon', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': sessionStorage.getItem('Authorization') || ''
      },
      body: JSON.stringify(params),
      signal: opinionController.signal
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const reader = response.body.getReader();
    const decoder = new TextDecoder('utf-8');
    let buffer = ''; // 用于处理跨chunk的数据
    let isStreamComplete = false; // 标记流是否完成
    
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      
      // 将新数据添加到缓冲区
      buffer += decoder.decode(value, { stream: true });
      
      // 按行分割，但保留最后一行（可能不完整）
      const lines = buffer.split('\n');
      buffer = lines.pop() || ''; // 保留最后一行
      
      for (const line of lines) {
        if (line.trim() === '') continue;
        
        // 查找data: 前缀
        if (line.startsWith('data: ')) {
          const jsonStr = line.substring(6);
          
          if (jsonStr === '[DONE]') {
            console.log('Opinion stream completed');
            isStreamComplete = true;
            continue;
          }
          
          try {
            const data = JSON.parse(jsonStr);
            
            // 检查是否是完整内容（流结束时的完整数据）
            if (data.content && typeof data.content === 'string' && isStreamComplete) {
              // 这是流结束后的完整内容，替换而不是追加
              const processedContent = data.content
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/\n/g, '<br>')
                .replace(/\r/g, '');
              
              opinionArticle.value = processedContent;
              console.log('Received complete opinion content after stream, replaced');
              // 自动滚动到最新内容
              if (opinionArticleRef.value) {
                opinionArticleRef.value.scrollTop = opinionArticleRef.value.scrollHeight;
              }
            }
            // 处理token
            else if (data.token) {
              const token = data.token;
              const processedToken = token
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/\n/g, '<br>')
                .replace(/\r/g, '');
              
              opinionArticle.value += processedToken;
              // 自动滚动到最新内容
              if (opinionArticleRef.value) {
                opinionArticleRef.value.scrollTop = opinionArticleRef.value.scrollHeight;
              }
            }
          } catch (error) {
            console.error('JSON parse error:', jsonStr, error);
          }
        }
        // 如果不是SSE格式，尝试直接解析JSON
        else {
          try {
            const data = JSON.parse(line);
            
            // 检查是否是完整内容
            if (data.content && typeof data.content === 'string' && isStreamComplete) {
              const processedContent = data.content
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/\n/g, '<br>')
                .replace(/\r/g, '');
              
              opinionArticle.value = processedContent;
              console.log('Received complete opinion content after stream, replaced');
              // 自动滚动到最新内容
              if (opinionArticleRef.value) {
                opinionArticleRef.value.scrollTop = opinionArticleRef.value.scrollHeight;
              }
            }
            // 处理token
            else if (data.token) {
              const token = data.token;
              const processedToken = token
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/\n/g, '<br>')
                .replace(/\r/g, '');
              
              opinionArticle.value += processedToken;
              // 自动滚动到最新内容
              if (opinionArticleRef.value) {
                opinionArticleRef.value.scrollTop = opinionArticleRef.value.scrollHeight;
              }
            }
          } catch (error) {
            // 不是JSON格式，忽略
          }
        }
      }
    }
  } catch (error) {
    if (error.name !== 'AbortError') {
      console.error('Opinion fetch error:', error);
      opinionArticle.value = '生成失败: ' + error.message;
    }
  } finally {
    clearTimeout(opinionTimeoutId);
    opinionController = null;
    isGeneratingOpinion.value = false; // 重置生成状态
  }
}

const generateTitle = async () => {
  // 如果正在生成中，直接返回
  if (isGeneratingArticle.value || isGeneratingOpinion.value || isGeneratingTitle.value) {
    return;
  }
  
  isGeneratingTitle.value = true; // 设置生成状态
  loadingDialog.value.show('正在生成标题，请稍候...');
  generatedTitle.value = ''; // 清空旧内容
  
  let reviewContent = window.localStorage.getItem('reviewContent');
  if (!reviewContent) {
    loadingDialog.value.hide();
    isGeneratingTitle.value = false; // 重置生成状态
    alert('请先选择楼盘，生成价值点');
    return;
  }

  reviewContent = JSON.parse(reviewContent);
  
  // 检查是否有必要的文章内容
  if (!opinionArticle.value && !streamingArticle.value) {
    loadingDialog.value.hide();
    isGeneratingTitle.value = false; // 重置生成状态
    alert('请先生成价值文章或评测文章');
    return;
  }

  let params = {
    estate_name: reviewContent.estate_name || '',
    opinion_content: opinionArticle.value || '',
    article_content: streamingArticle.value || '',
    style: titleStyle.value || '',
    type: titleType.value || ''
  }

  try {
    const response = await axios.post('/media/predict/test/create/title/by/point/with/content', params, {
      headers: {
        'Authorization': sessionStorage.getItem('Authorization') || ''
      }
    });

    console.log('Title generation response:', response);
    
    if (response.data && response.data.res) {
      generatedTitle.value = response.data.res.replace(/\n/g, '<br>');
    } else {
      generatedTitle.value = '生成失败: 未返回有效数据';
    }
  } catch (error) {
    console.error('Title generation error:', error);
    generatedTitle.value = '生成失败: ' + (error.response?.data?.message || error.message);
  } finally {
    loadingDialog.value.hide();
    isGeneratingTitle.value = false; // 重置生成状态
  }
}

const onEstateSearch = (search, loading) => {
  if (search.length) {
    loading(true);
    axios.post('/api/erp/get/searchEstateName', {
      search: search
    })
    .then(response => {
      if (response.data && Array.isArray(response.data.data)) {
        estateOptions.value = response.data.data.map(item => ({
          label: item.real_estate_name,
          id: item.id
        }));
      } else {
        estateOptions.value = [];
      }
    })
    .catch(error => {
      console.error("Estate search API call failed:", error);
      estateOptions.value = [];
    })
    .finally(() => {
      loading(false);
    });
  }
};

const handleSearch = async () => {
  if (!selectedEstate.value) {
    alert('请先选择楼盘');
    return;
  }

  try {
    // 首先调用楼盘名搜索接口
    const searchResponse = await axios.post('/api/erp/test/get/agent/632', {
      search: selectedEstate.value.label
    });

    console.log('Estate search response:', searchResponse);

    // 然后调用添加楼盘信息接口
    const addResponse = await axios.post('/media/predict/test/add/estate/search/name', {
      keyword: selectedEstate.value.label || ''
    }, {
      headers: {
        'Authorization': sessionStorage.getItem('Authorization') || ''
      }
    });
    
    // 显示添加结果
    if (addResponse.data && addResponse.data.message) {
      alert(addResponse.data.message);
    } else {
      alert('添加完成，但未返回有效数据');
    }
    
    // 清空选择
    selectedEstate.value = null;
  } catch (error) {
    console.error('Search error:', error);
    alert('操作失败: ' + (error.response?.data?.message || error.message)); 
  }
}

const buttons = ref([])
    
const activeButtonId = ref(null);

const loadHistory = () => {
  const history = JSON.parse(window.localStorage.getItem('generationHistory')) || [];
  if (Array.isArray(history)) {
    buttons.value = history.map(record => ({
      id: record.id,
      label: record.create_time
    }));
  }

  if (buttons.value.length > 0 && (!activeButtonId.value || !buttons.value.some(b => b.id === activeButtonId.value))) {
    const latestButton = buttons.value[0];
    activeButtonId.value = latestButton.id;
    handleButtonClick(latestButton, true);
  }
};

const handleButtonClick = (button, isInitialLoad = false) => {
  if (!isInitialLoad) {
    console.log('Clicked:', button.label);
  }
  activeButtonId.value = button.id;
  
  const history = JSON.parse(window.localStorage.getItem('generationHistory')) || [];
  const selectedRecord = history.find(record => record.id === button.id);

  if (selectedRecord) {
    let opinion_article = selectedRecord.opinion_article || ''
    let article_content = selectedRecord.content || ''
    opinionArticle.value = opinion_article.replace(/\n/g, '<br>');
    streamingArticle.value = article_content.replace(/\n/g, '<br>');
  }
}

onMounted(() => {
  loadHistory();
  window.addEventListener('history-updated', loadHistory);
});

// 组件卸载时取消未完成的请求
onUnmounted(() => {
  if (controller) {
    controller.abort();
    controller = null;
  }
  if (opinionController) {
    opinionController.abort();
    opinionController = null;
  }
  if (updateTimer) {
    clearTimeout(updateTimer);
  }
  if (opinionUpdateTimer) {
    clearTimeout(opinionUpdateTimer);
  }
  // 重置所有生成状态
  isGeneratingArticle.value = false;
  isGeneratingOpinion.value = false;
  isGeneratingTitle.value = false;
  window.removeEventListener('history-updated', loadHistory);
});
</script>

<style scoped>
.right-panel {
  width: 60%;
  padding: 40px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  height: auto;
  overflow-y: visible;
}

.content-column {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
  height: auto;
  overflow-y: visible;
}

.article-section {
  display: flex;
  flex-direction: column;
  gap: 15px;
  width: 100%;
  flex-shrink: 0;
}

.article-header {
  display: flex;
  gap: 15px;
  align-items: flex-start;
  justify-content: space-between;
  width: 100%;
}

.spacer {
  flex: 1;
}

.article-row {
  display: flex;
  gap: 20px;
  width: 100%;
  align-items: flex-start;
  height: auto;
  min-height: fit-content;
}

.generate-article-btn {
  min-width: 160px;
  height: fit-content;
  padding: 14px 20px;
  font-size: 1.1em;
  font-weight: 600;
  white-space: nowrap;
  border: none;
  border-radius: 12px;
  background: linear-gradient(135deg, #fdd835 0%, #f9a825 100%);
  color: #2c3e50;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 2px 8px rgba(253, 216, 53, 0.3);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  flex-shrink: 0;
}

.generate-article-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(253, 216, 53, 0.4);
  background: linear-gradient(135deg, #f9a825 0%, #fdd835 100%);
}

.generate-article-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 8px rgba(253, 216, 53, 0.3);
}

.generate-article-btn:disabled {
  background: #cccccc;
  color: #666666;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
  opacity: 0.6;
}

.generate-article-btn:disabled:hover {
  transform: none;
  box-shadow: none;
  background: #cccccc;
}

.display-box {
  flex: 1;
  border: 1px solid var(--border-color, #EAEAEA);
  border-radius: 8px;
  padding: 20px;
  background-color: var(--panel-bg-color, #fff);
  line-height: 1.7;
  color: var(--text-color, #5D4037);
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.05);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  height: 400px;
  min-height: 400px;
  max-height: 400px;
  overflow: hidden;
  resize: vertical;
}

.display-box > div {
  width: 100%;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  -ms-overflow-style: auto;
}

.display-box > div::-webkit-scrollbar {
  width: 8px;
}

.display-box > div::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.display-box > div::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

.display-box > div::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 占位符样式 */
.placeholder {
  text-align: center;
  color: #aaa;
  width: 100%;
}

.placeholder-icon {
  margin-bottom: 16px;
}

.placeholder h3 {
  margin: 0 0 8px 0;
  font-size: 1.2em;
  color: #bbb;
}

.placeholder p {
  margin: 0;
  line-height: 1.6;
}

/* 历史记录样式 */
.history-box {
  width: 100%;
  position: relative;
  padding: 15px 20px;
  background: #fff;
  border-radius: 8px;
  border: 1px solid #EAEAEA;
  overflow: hidden;
}

.history-title {
  margin: 0 0 15px 0;
  font-weight: 600;
  color: #333;
  font-size: 1em;
}

.scroll-container {
  width: 100%;
  overflow-x: auto;
  white-space: nowrap;
  scrollbar-width: thin;
  -ms-overflow-style: auto;
  padding-bottom: 5px;
}

.scroll-container::-webkit-scrollbar {
  height: 6px;
  display: block;
}

.scroll-container::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.scroll-container::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.scroll-container::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

.button-wrapper {
  display: inline-flex;
  gap: 10px;
}

.no-history {
  color: #999;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 10px 0;
}

.scroll-button {
  padding: 10px 20px;
  border: none;
  border-radius: 8px;
  background-color: #f5f5f5;
  color: #555;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  flex-shrink: 0;
}

.scroll-button:hover {
  background-color: #e8e8e8;
  color: #222;
}

.scroll-button:active {
  transform: scale(0.98);
}

.scroll-button.active {
  background-color: #fdd835;
  color: #000;
  font-weight: 600;
  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}

/* 搜索区域样式 */
.search-box {
  width: 100%;
  position: relative;
  padding: 15px 20px;
  background: #fff;
  border-radius: 8px;
  border: 1px solid #EAEAEA;
}

.search-title {
  margin: 0 0 15px 0;
  font-weight: 600;
  color: #333;
  font-size: 1em;
}

.search-container {
  display: flex;
  gap: 10px;
  align-items: center;
}

.estate-select {
  flex: 1;
}

/* vue-select override styles for estate search */
:deep(.estate-select .vs__dropdown-toggle) {
  height: 100%;
  padding: 12px 16px;
  border-radius: 8px;
  border: 2px solid #e1e5e9;
  background-color: #fafbfc;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

:deep(.estate-select .vs__dropdown-toggle:hover) {
  border-color: #cbd5e0;
  background-color: #ffffff;
}

:deep(.estate-select.vs--open .vs__dropdown-toggle) {
  border-color: #fdd835;
  background-color: #ffffff;
  box-shadow: 0 0 0 3px rgba(253, 216, 53, 0.15);
}

:deep(.estate-select .vs__search::placeholder) {
  color: #94a3b8;
}

.search-btn {
  padding: 12px 20px;
  border: none;
  border-radius: 8px;
  background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
  color: white;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  white-space: nowrap;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.search-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
  background: linear-gradient(135deg, #45a049 0%, #4CAF50 100%);
}

.search-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3);
}

.search-btn:disabled {
  background: #cccccc;
  color: #666666;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.search-btn:disabled:hover {
  transform: none;
  box-shadow: none;
  background: #cccccc;
}

.article-controls {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 160px;
  width: 160px;
}

.template-input-container {
  flex: 1;
  min-width: 0;
  margin-right: auto;
}

.template-input {
  width: 100%;
  min-height: 80px;
  padding: 16px;
  border: 2px solid #e1e5e9;
  border-radius: 12px;
  background-color: #fafbfc;
  font-size: 14px;
  line-height: 1.6;
  color: #2c3e50;
  resize: vertical;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.template-input:hover {
  border-color: #cbd5e0;
  background-color: #ffffff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.template-input:focus {
  border-color: #fdd835;
  background-color: #ffffff;
  box-shadow: 0 0 0 3px rgba(253, 216, 53, 0.15), 0 4px 12px rgba(0, 0, 0, 0.1);
  outline: none;
  transform: translateY(-1px);
}

.template-input::placeholder {
  color: #94a3b8;
  font-style: normal;
  font-weight: 400;
}

.title-controls {
  display: flex;
  gap: 12px;
  align-items: center;
}

.title-select {
  padding: 12px 16px;
  border: 2px solid #e1e5e9;
  border-radius: 8px;
  background-color: #fafbfc;
  font-size: 14px;
  color: #2c3e50;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  min-width: 120px;
}

.title-select:hover {
  border-color: #cbd5e0;
  background-color: #ffffff;
}

.title-select:focus {
  border-color: #fdd835;
  background-color: #ffffff;
  box-shadow: 0 0 0 3px rgba(253, 216, 53, 0.15);
  outline: none;
}

.title-select option {
  padding: 8px;
  background-color: #ffffff;
  color: #2c3e50;
}
</style>